home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / upc12bs1.zip / UUCICO / ulibwin.c < prev    next >
C/C++ Source or Header  |  1993-10-03  |  28KB  |  771 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       u l i b w i n . C                                            */
  3. /*                                                                    */
  4. /*       UUPC/extended serial port communications for Windows 3.1     */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Changes copyright (c) 1993, by Robert Denny                  */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  13. /*       Wonderworks.                                                 */
  14. /*                                                                    */
  15. /*       All rights reserved except those explicitly granted by       */
  16. /*       the UUPC/extended license agreement.                         */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /*                          RCS Information                           */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. /*
  24.  *    $Id: ulibwin.c 1.7 1993/10/03 22:09:09 ahd Exp $
  25.  *
  26.  *    Revision history:
  27.  *    $Log: ulibwin.c $
  28.  * Revision 1.7  1993/10/03  22:09:09  ahd
  29.  * Use unsigned long to display speed
  30.  *
  31.  * Revision 1.6  1993/10/01  02:36:45  dmwatt
  32.  * Suppress odd debugging messages in normal compile
  33.  * Reformat source
  34.  *
  35.  * Revision 1.5  1993/09/29  13:18:06  ahd
  36.  * Use new dummy setprty function
  37.  *
  38.  * Revision 1.4  1993/09/27  00:48:43  ahd
  39.  * Add dummy set and reset priority functions
  40.  *
  41.  * Revision 1.3  1993/08/02  03:24:59  ahd
  42.  * Further changes in support of Robert Denny's Windows 3.x support
  43.  *
  44.  * Revision 1.2  1993/07/31  16:27:49  ahd
  45.  * Changes in support of Robert Denny's Windows support
  46.  *
  47.  * Revision 1.1  1993/07/22  23:24:23  ahd
  48.  * Initial revision
  49.  *
  50.  */
  51.  
  52. /*--------------------------------------------------------------------*/
  53. /*       Services provided by ulib.c:                                 */
  54. /*                                                                    */
  55. /*          - serial I/O                                              */
  56. /*--------------------------------------------------------------------*/
  57.  
  58. /*--------------------------------------------------------------------*/
  59. /*                        System include files                        */
  60. /*--------------------------------------------------------------------*/
  61.  
  62. #include <stdlib.h>
  63. #include <stdio.h>
  64. #include <string.h>
  65. #include <fcntl.h>
  66. #include <io.h>
  67. #include <time.h>
  68.  
  69. /*--------------------------------------------------------------------*/
  70. /*                    MS Windows 3.1 include files                    */
  71. /*--------------------------------------------------------------------*/
  72.  
  73. #include <windows.h>
  74.  
  75. /*--------------------------------------------------------------------*/
  76. /*                    UUPC/extended include files                     */
  77. /*--------------------------------------------------------------------*/
  78.  
  79. #include "lib.h"
  80. #include "ulib.h"
  81. #include "ssleep.h"
  82. #include "commlib.h"
  83.  
  84. //
  85. // Finally, Microsoft has documented a way to see the Modem Status
  86. // Register bits for modem control lines. This was a real bizarre
  87. // mess with SetCommEventMask() and GetCommEventMask(). The document
  88. // is in the Developer's Knowledge Base:
  89. //
  90. // Title: INF: Accessing the Modem Status Register (MSR) in Windows
  91. // Document Number: Q101417           Publ Date: 15-JUL-1993
  92. // Product Name: Microsoft Windows Software Development Kit
  93. // Product Version:  3.10
  94. // Operating System: WINDOWS
  95. //
  96.  
  97. #define COMM_MSRSHADOW 35          // Offset in DEB of MSR shadow
  98. #define MSR_CTS              0x10  // absolute CTS state in MSR
  99. #define MSR_DSR              0x20  // absolute DSR state in MSR
  100. #define MSR_RI               0x40  // absolute RI state in MSR
  101. #define MSR_RLSD             0x80  // absolute RLSD state in MSR
  102.  
  103. currentfile();
  104.  
  105. static boolean   carrierdetect = FALSE;  /* Modem is not connected     */
  106.  
  107. static boolean hangupNeeded = FALSE;
  108. static UINT currentSpeed = 0;
  109. static LPBYTE lpbModemBits;       // --> Modem Status Register bits
  110.  
  111. #define FAR_NULL ((PVOID) 0L)
  112.  
  113. #define IN_QUEUE_SIZE   2048
  114. #define OUT_QUEUE_SIZE  2048
  115. #define IN_XOFF_LIM     256
  116. #define IN_XON_LIM      256
  117.  
  118. /*--------------------------------------------------------------------*/
  119. /*         Definitions of control structures for Win 3.1 API          */
  120. /*--------------------------------------------------------------------*/
  121.  
  122. static int nCid;
  123. static DCB dcb;
  124.  
  125. /*--------------------------------------------------------------------*/
  126. /*                        Internal prototypes                         */
  127. /*--------------------------------------------------------------------*/
  128.  
  129. static void ShowModem( void );
  130. static void ShowError( int status );
  131.  
  132. /*--------------------------------------------------------------------*/
  133. /*    n o p e n l i n e                                               */
  134. /*                                                                    */
  135. /*    Open the serial port for I/O                                    */
  136. /*--------------------------------------------------------------------*/
  137.  
  138. #ifdef __TURBOC__
  139. #pragma argsused
  140. #endif
  141.  
  142. int nopenline(char *name, BPS baud, const boolean direct )
  143. {
  144.    int rc;
  145.  
  146.    if (portActive)               /* Was the port already active?     ahd   */
  147.       closeline();               /* Yes --> Shutdown it before open  ahd   */
  148.  
  149. #ifdef UDEBUG
  150.    printmsg(15, "openline: %s, %ul", name, (unsigned long) baud);
  151. #endif
  152.  
  153.    if (!equaln(name, "COM", 3 ))
  154.    {
  155.       printmsg(0,
  156.          "openline: Communications port must be format COMx, was %s",
  157.          name);
  158.       return TRUE;
  159.    }
  160.  
  161.    if((nCid = OpenComm(name, IN_QUEUE_SIZE, OUT_QUEUE_SIZE)) < 0)
  162.    {
  163.       printmsg(0, "openline: Failed to open port %s.", name);
  164.       printmsg(0, "nopenline: %s: OpenComm returned %#04X (%d)",
  165.                    name,
  166.                    nCid,
  167.                    nCid);
  168.       return TRUE;
  169.    }
  170.  
  171. /*--------------------------------------------------------------------*/
  172. /*        Get the pointer to the MSR shadow in COMM.DRV's DEB         */
  173. /*--------------------------------------------------------------------*/
  174.  
  175.    lpbModemBits = (LPBYTE)SetCommEventMask(nCid, 0) + COMM_MSRSHADOW;
  176.  
  177. /*--------------------------------------------------------------------*/
  178. /*            Reset any errors on the communications port             */
  179. /*--------------------------------------------------------------------*/
  180.  
  181.    if ((rc = GetCommError (nCid, NULL)) != 0)
  182.    {
  183.       printmsg(0, "openline: Error condition reset on port %s.", name);
  184.       ShowError(rc);
  185.    }
  186.  
  187. /*--------------------------------------------------------------------*/
  188. /*                           Set baud rate                            */
  189. /*--------------------------------------------------------------------*/
  190.  
  191.    nSIOSpeed(baud);
  192.  
  193. /*--------------------------------------------------------------------*/
  194. /*                        Set line attributes                         */
  195. /*--------------------------------------------------------------------*/
  196.  
  197.    printmsg(15,"openline: Getting attributes");
  198.    if ((rc = GetCommState(nCid, &dcb)) != 0)
  199.    {
  200.       printmsg(0,"nopenline: %s: GetCommState was %#04x (%d)",
  201.                   name,
  202.                   rc,
  203.                   rc);
  204.       panic();
  205.    }
  206.  
  207.    dcb.StopBits = ONESTOPBIT;
  208.    dcb.Parity = NOPARITY;
  209.    dcb.ByteSize = 8;
  210.  
  211. /*--------------------------------------------------------------------*/
  212. /*                      Set up for Flow Control                       */
  213. /*--------------------------------------------------------------------*/
  214.  
  215.    printmsg(15,"openline: Disabling XON/XOFF flow control");
  216.  
  217.    dcb.fOutX = 0;
  218.    dcb.fInX = 0;
  219.    if(!direct)                 // nodirect means RTS/CTS flow OK
  220.    {
  221. #ifdef UDEBUG
  222.       printmsg(15, "openline: Enabling RTS/CTS flow control");
  223. #endif
  224.       dcb.fOutxCtsFlow = 1;
  225.       dcb.fRtsflow = 1;
  226.       dcb.XoffLim = IN_XOFF_LIM;
  227.       dcb.XonLim = IN_XON_LIM;
  228.    }
  229.    else {
  230. #ifdef UDEBUG
  231.       printmsg(4, "openline: Disabling RTS/CTS flow control");
  232. #endif
  233.       dcb.fOutxCtsFlow = 0;
  234.       dcb.fRtsflow = 0;
  235.    }
  236.  
  237. /*--------------------------------------------------------------------*/
  238. /*                Set up for Modem Control as needed                  */
  239. /*--------------------------------------------------------------------*/
  240.  
  241.    dcb.fDtrDisable = 0;
  242.    dcb.fRtsDisable = 0;
  243.  
  244. /*--------------------------------------------------------------------*/
  245. /*              Modify the DCB with the new attributes                */
  246. /*--------------------------------------------------------------------*/
  247.  
  248. #ifdef UDEBUG
  249.    printmsg(15,"openline: Setting attributes");
  250. #endif
  251.  
  252.    if ((rc = SetCommState(&dcb)) != 0)
  253.    {
  254.       printmsg(0,"nopenline: %s: return code from SetCommState was %#04X (%d)",
  255.                  name,
  256.                  rc,
  257.                  rc);
  258.       panic();
  259.    }
  260.  
  261. /*--------------------------------------------------------------------*/
  262. /*                 Assure RTS and DTR are asserted                    */
  263. /*--------------------------------------------------------------------*/
  264.  
  265.  
  266. #ifdef UDEBUG
  267.    printmsg(15,"openline: Raising RTS/DTR");
  268. #endif
  269.  
  270.    if (EscapeCommFunction(nCid, SETRTS) != 0)
  271.    {
  272.       printmsg(0, "openline: Failed to raise RTS for %s", name);
  273.       panic();
  274.    }
  275.    if (EscapeCommFunction(nCid, SETDTR) != 0)
  276.    {
  277.       printmsg(0, "openline: Unable to raise DTR for %s", name);
  278.       panic();
  279.    }
  280.  
  281.    ShowModem();
  282.  
  283. /*--------------------------------------------------------------------*/
  284. /*        Log serial line data only if log file already exists        */
  285. /*--------------------------------------------------------------------*/
  286.  
  287.    traceStart( name );
  288.  
  289.    portActive = TRUE;     /* record status for error handler */
  290.  
  291. /*--------------------------------------------------------------------*/
  292. /*                     Wait for port to stablize                      */
  293. /*--------------------------------------------------------------------*/
  294.  
  295.    ssleep(2);              /* Allow port to stabilize per V.24  */
  296.  
  297.    return 0;
  298.  
  299. } /* nopenline */
  300.  
  301. /*--------------------------------------------------------------------*/
  302. /*    s r e a d                                                       */
  303. /*                                                                    */
  304. /*    Read from the serial port                                       */
  305. /*                                                                    */
  306. /*   Non-blocking read essential to "g" protocol. The rather cryptic  */
  307. /*   "description" in dcpgpkt.c is:                                   */
  308. /*                                                                    */
  309. /*   sread(buf, n, timeout)                                           */
  310. /*      while(TRUE)                                                   */
  311. /*         if # of chars available >= n (w/o dec internal counter)    */
  312. /*            read n chars into buf (dec internal counter)            */
  313. /*            break                                                   */
  314. /*         else                                                       */
  315. /*            if time > timeout                                       */
  316. /*               break                                                */
  317. /*                                                                    */
  318. /*   NOTE: Timeout of 0 returns right away, indicating the number of  */
  319. /*         bytes in our local receive buffer. There's GOTTA be a      */
  320. /*         better way...                                              */
  321. /*                                                                    */
  322. /*   This all changes in a multi-tasking system.  Requests for I/O    */
  323. /*   should get queued and an event flag given.  Then the             */
  324. /*   requesting process (e.g. gmachine()) waits for the event flag    */
  325. /*   to fire processing either a read or a write.  Could be           */
  326. /*   implemented on VAX/VMS or DG but not MS-DOS.                     */
  327. /*                                                                    */
  328. /*--------------------------------------------------------------------*/
  329.  
  330. unsigned int nsread(char *output, unsigned int wanted, unsigned int timeout)
  331.  
  332. {
  333.    int rc, received;
  334.    time_t stop_time;
  335.    time_t now;
  336.    COMSTAT stat;
  337.  
  338.    //
  339.    // This catches a fencepost condition later...
  340.    //
  341.  
  342.    if (wanted == 0)
  343.    {
  344.       ddelay(0);
  345.       return(0);
  346.    }
  347.  
  348. /*--------------------------------------------------------------------*/
  349. /*                      Report our modem status                       */
  350. /*--------------------------------------------------------------------*/
  351.  
  352.   ShowModem();
  353.  
  354. /*--------------------------------------------------------------------*/
  355. /*                 Determine when to stop processing                  */
  356. /*--------------------------------------------------------------------*/
  357.  
  358.    if ( timeout == 0 )        /* 0 = don't wait around.               */
  359.    {
  360.       stop_time = 0;
  361.       now = 1;                /* Any number greater than stop time    */
  362.    }
  363.    else {
  364.       time( & now );
  365.       stop_time = now + timeout;
  366.    }
  367.  
  368. /*--------------------------------------------------------------------*/
  369. /*       Watch RX Queue till wanted bytes available or timeout        */
  370. /*--------------------------------------------------------------------*/
  371.  
  372.    while(TRUE)
  373.    {
  374.  
  375.       //
  376.       // Check & clear the comm port. This gets the #chars in the
  377.       // receive queue as well, in the COMSTAT structure.
  378.       //
  379.  
  380.       if ((rc = GetCommError(nCid, &stat)) != 0)
  381.       {
  382.          printmsg(0,"sread: Read of %d bytes failed.", wanted);
  383.          printmsg(0,"       return code from GetCommError was %#04x (%d)",
  384.                                                 rc , rc);
  385.          ShowError(rc);
  386.          return 0;
  387.       }
  388.  
  389.       //
  390.       // If wanted # bytes are available, break out and read 'em.
  391.       //
  392.  
  393.       if (stat.cbInQue >= wanted)
  394.          break;               // We have enough, break out!
  395.  
  396.       //
  397.       // Be friendly to Windows' cooperative multitasking...
  398.       //
  399.  
  400.       ddelay(0);
  401.  
  402.       //
  403.       // If timeout is zero, return immediately.
  404.       //
  405.  
  406.       if (stop_time == 0)
  407.          return(stat.cbInQue);
  408.  
  409.       //
  410.       // Check for timeout. If timed out, return.
  411.       //
  412.  
  413.       time( &now );
  414.       if(stop_time <= now)
  415.       {
  416.          printmsg(15, "sread: timeout(%d) - %d chars avail",
  417.                          timeout, stat.cbInQue);
  418.          return(stat.cbInQue);
  419.       }
  420.  
  421.    } // end of while(TRUE)
  422.  
  423.    //
  424.    // We have enough in the RX queue. Grab 'em right into the
  425.    // caller's buffer.
  426.    //
  427.  
  428.    received = ReadComm(nCid, output, wanted);
  429.  
  430.    printmsg(15, "sread: Got %d characters, %d still in RX queue.",
  431.                    (int)received, (int)(stat.cbInQue - received));
  432.  
  433. /*--------------------------------------------------------------------*/
  434. /*                    Log the newly received data                     */
  435. /*--------------------------------------------------------------------*/
  436.  
  437.    traceData( output, wanted, FALSE );
  438.  
  439.    return(received);
  440.  
  441. } /* nsread */
  442.  
  443. /*--------------------------------------------------------------------*/
  444. /*    n s w r i t e                                                   */
  445. /*                                                                    */
  446. /*    Write to the serial port                                        */
  447. /*--------------------------------------------------------------------*/
  448.  
  449. int nswrite(const char *data, unsigned int len)
  450. {
  451.    int bytes;
  452.    int rc;
  453.  
  454.    hangupNeeded = TRUE;      /* Flag that the port is now dirty  */
  455.  
  456. /*--------------------------------------------------------------------*/
  457. /*                      Report our modem status                       */
  458. /*--------------------------------------------------------------------*/
  459.  
  460.    ShowModem();
  461.  
  462. /*--------------------------------------------------------------------*/
  463. /*         Write the data out as the queue becomes available          */
  464. /*--------------------------------------------------------------------*/
  465.  
  466.    bytes = WriteComm(nCid, data, len);
  467.  
  468.    rc = GetCommError(nCid, NULL);
  469.    if (rc)
  470.    {
  471.       printmsg(0,"nswrite: WriteComm failed, "
  472.                  "return code from GetCommError was %#04x (%d)",
  473.                         rc , rc);
  474.       ShowError(rc);
  475.       return bytes;
  476.    }
  477.  
  478. /*--------------------------------------------------------------------*/
  479. /*                        Log the data written                        */
  480. /*--------------------------------------------------------------------*/
  481.  
  482.    traceData( data, len, TRUE );
  483.  
  484. /*--------------------------------------------------------------------*/
  485. /*            Return bytes written to the port to the caller          */
  486. /*--------------------------------------------------------------------*/
  487.  
  488.    return len;
  489.  
  490. } /* nswrite */
  491.  
  492. /*--------------------------------------------------------------------*/
  493. /*    n s s e n d b r k                                               */
  494. /*                                                                    */
  495. /*    send a break signal out the serial port                         */
  496. /*--------------------------------------------------------------------*/
  497.  
  498. void nssendbrk(unsigned int duration)
  499. {
  500.  
  501.  
  502. #ifdef UDEBUG
  503.    printmsg(12, "ssendbrk: %d", duration);
  504. #endif
  505.  
  506.    SetCommBreak(nCid);
  507.    ddelay(duration == 0 ? 200 : duration);
  508.    ClearCommBreak(nCid);
  509.  
  510. } /*ssendbrk*/
  511.  
  512. /*--------------------------------------------------------------------*/
  513. /*    n c l o s e l i n e                                             */
  514. /*                                                                    */
  515. /*    Close the serial port down                                      */
  516. /*--------------------------------------------------------------------*/
  517.  
  518. void ncloseline(void)
  519. {
  520.  
  521.    if ( ! portActive )
  522.       panic();
  523.  
  524.    portActive = FALSE;     /* flag port closed for error handler  */
  525.    hangupNeeded = FALSE;  /* Don't fiddle with port any more     */
  526.  
  527. /*--------------------------------------------------------------------*/
  528. /*                             Lower DTR                              */
  529. /*--------------------------------------------------------------------*/
  530.  
  531.     if (EscapeCommFunction(nCid, CLRDTR | CLRRTS) != 0)
  532.         printmsg(0,"closeline: Unable to lower DTR/RTS");
  533.  
  534. /*--------------------------------------------------------------------*/
  535. /*                      Actually close the port                       */
  536. /*--------------------------------------------------------------------*/
  537.  
  538.    if(CloseComm(nCid) != 0)
  539.       printmsg(0, "closeline: close of serial port failed");
  540.  
  541. /*--------------------------------------------------------------------*/
  542. /*                   Stop logging the data to disk                    */
  543. /*--------------------------------------------------------------------*/
  544.  
  545.    traceStop();
  546.  
  547.    printmsg(3,"Serial port closed");
  548.  
  549. } /* ncloseline */
  550.  
  551. /*--------------------------------------------------------------------*/
  552. /*    n h a n g u p                                                   */
  553. /*                                                                    */
  554. /*    Hangup the telephone by dropping DTR.  Works with HAYES and     */
  555. /*    many compatibles.                                               */
  556. /*    14 May 89 Drew Derbyshire                                       */
  557. /*--------------------------------------------------------------------*/
  558.  
  559. void nhangup( void )
  560. {
  561.    hangupNeeded = FALSE;
  562.  
  563. /*--------------------------------------------------------------------*/
  564. /*                              Drop DTR                              */
  565. /*--------------------------------------------------------------------*/
  566.  
  567.    if (EscapeCommFunction(nCid, CLRDTR) != 0)
  568.    {
  569.       printmsg(0, "hangup: Unable to lower DTR for comm port");
  570.       panic();
  571.    }
  572.  
  573. /*--------------------------------------------------------------------*/
  574. /*                  Wait for the telephone to hangup                  */
  575. /*--------------------------------------------------------------------*/
  576.  
  577.    printmsg(3,"hangup: Dropped DTR");
  578.    ddelay(1000);            /* Really only need 250 milliseconds (HA) */
  579.  
  580. /*--------------------------------------------------------------------*/
  581. /*                          Bring DTR backup                          */
  582. /*--------------------------------------------------------------------*/
  583.  
  584.    if (EscapeCommFunction(nCid, SETDTR) != 0)
  585.    {
  586.       printmsg(0, "hangup: Unable to raise DTR for comm port");
  587.       panic();
  588.    }
  589.    ddelay(500);         /* Now wait for the poor thing to recover    */
  590.  
  591. } /* nhangup */
  592.  
  593. /*--------------------------------------------------------------------*/
  594. /*       S I O S p e e d                                              */
  595. /*                                                                    */
  596. /*       Re-specify the speed of an opened serial port                */
  597. /*--------------------------------------------------------------------*/
  598.  
  599. void nSIOSpeed(BPS baud)
  600. {
  601.    WORD rc;
  602.  
  603.    currentSpeed = (UINT) baud;
  604.    printmsg(15,"SIOSpeed: Setting baud rate to %lu",
  605.                (unsigned long) currentSpeed);
  606.  
  607.    ShowModem();
  608.    GetCommState (nCid, &dcb);
  609.  
  610.    dcb.BaudRate = currentSpeed;
  611.    rc = SetCommState (&dcb);
  612.  
  613.    if (rc)
  614.    {
  615.       printmsg(0,"SIOSPeed: Unable to set baud rate for port to %lu",
  616.                  (unsigned long) currentSpeed);
  617.       panic();
  618.    }
  619.  
  620. } /* nSIOSpeed */
  621.  
  622. /*--------------------------------------------------------------------*/
  623. /*    n f l o w c o n t r o l                                         */
  624. /*                                                                    */
  625. /*    Enable/Disable in band (XON/XOFF) flow control                  */
  626. /*--------------------------------------------------------------------*/
  627.  
  628. void nflowcontrol( boolean flow )
  629. {
  630.    int rc;
  631.    DCB dcb;
  632.  
  633.    GetCommState(nCid, &dcb);
  634.  
  635.    if (flow)
  636.    {
  637.       dcb.fOutX = TRUE;
  638.       dcb.fInX = TRUE;
  639.       dcb.fRtsflow = FALSE;
  640.       dcb.fOutxCtsFlow = FALSE;
  641.    }
  642.    else {
  643.       dcb.fOutX = FALSE;
  644.       dcb.fInX = FALSE;
  645.       dcb.fRtsflow = TRUE;
  646.       dcb.fOutxCtsFlow = TRUE;
  647.    }
  648.  
  649.    if ((rc = SetCommState(&dcb)) != 0)
  650.    {
  651.       printmsg(0,"flowcontrol: Unable to set flow control");
  652.       printmsg(0,"Return code fromSetCommState was %#04x (%d)",
  653.                   (int) rc,
  654.                   (int) rc);
  655.       panic();
  656.    } /*if */
  657.  
  658. } /* nflowcontrol */
  659.  
  660. /*--------------------------------------------------------------------*/
  661. /*    n G e t S p e e d                                               */
  662. /*                                                                    */
  663. /*    Report current speed of communications connection               */
  664. /*--------------------------------------------------------------------*/
  665.  
  666. BPS nGetSpeed( void )
  667. {
  668.    return currentSpeed;
  669. } /* GetSpeed */
  670.  
  671. /*--------------------------------------------------------------------*/
  672. /*   n C D                                                            */
  673. /*                                                                    */
  674. /*   Return status of carrier detect                                  */
  675. /*--------------------------------------------------------------------*/
  676.  
  677. boolean nCD( void )
  678. {
  679.    boolean online = carrierdetect;
  680.    boolean modem_present;
  681.  
  682.    carrierdetect = ((*lpbModemBits & MSR_RLSD) != 0);
  683.    modem_present = ((*lpbModemBits & MSR_DSR) != 0);
  684.  
  685. /*--------------------------------------------------------------------*/
  686. /*    If we previously had carrier detect but have lost it, we        */
  687. /*    report it was lost.  If we do not yet have carrier detect,      */
  688. /*    we return success because we may not have connected yet.        */
  689. /*    If DSR is not present, we always report no carrier, as there    */
  690. /*    is either no modem at all(!) or it's not turned on.             */
  691. /*--------------------------------------------------------------------*/
  692.  
  693.    if (online)
  694.       return (modem_present && carrierdetect);
  695.    else
  696.       return (modem_present);
  697.  
  698. } /* nCD */
  699.  
  700. /*--------------------------------------------------------------------*/
  701. /*    S h o w M o d e m                                               */
  702. /*                                                                    */
  703. /*    Report current modem status when changed from last call         */
  704. /*--------------------------------------------------------------------*/
  705.  
  706. #define mannounce(flag, bits, text ) (((flag & bits) != 0) ? text : "" )
  707.  
  708. static void ShowModem( void )
  709. {
  710.    BYTE modem_bits = *lpbModemBits;
  711.    static BYTE old_bits = 0xFF;
  712.  
  713.    if ( debuglevel < 4 )
  714.       return;
  715.  
  716.    if ( (debuglevel < 4) ||            // Silent at lower debuglevels
  717.       (modem_bits == old_bits))        // Show only changes in modem signals
  718.       return;
  719.  
  720.    printmsg(0, "ShowModem: %#02x %s %s %s",
  721.                 modem_bits,
  722.                 mannounce(MSR_RLSD,  modem_bits, "DCD"),
  723.                 mannounce(MSR_DSR,   modem_bits, "DSR"),
  724.                 mannounce(MSR_CTS,   modem_bits, "CTS"));
  725.    old_bits = modem_bits;
  726.  
  727. } /* ShowModem */
  728.  
  729. /*--------------------------------------------------------------------*/
  730. /*    S h o w E r r o r                                               */
  731. /*                                                                    */
  732. /*    Report modem error bits in English (more or less)               */
  733. /*--------------------------------------------------------------------*/
  734.  
  735. static void ShowError( int status )
  736. {
  737.    printmsg(2, "Port Error: %#04x%s%s%s%s%s",
  738.       status,
  739.       mannounce(CE_RXOVER,   status, " Recv Queue Ovfl"),
  740.       mannounce(CE_OVERRUN,  status, " Hardware Overrun"),
  741.       mannounce(CE_RXPARITY, status, " Parity Error"),
  742.                 mannounce(CE_FRAME,    status, " Framing Error"),
  743.                 mannounce(CE_TXFULL,   status, " Xmit Queue Full"));
  744.  
  745. } /* ShowError */
  746.  
  747. /*--------------------------------------------------------------------*/
  748. /*       s e t P r t y                                                */
  749. /*                                                                    */
  750. /*       No operation under Windows                                   */
  751. /*--------------------------------------------------------------------*/
  752.  
  753. #ifdef __TURBOC__
  754. #pragma argsused
  755. #endif
  756.  
  757. void setPrty( const KEWSHORT priorityIn, const KEWSHORT prioritydeltaIn )
  758. {
  759.  
  760. } /* setPrty */
  761.  
  762. /*--------------------------------------------------------------------*/
  763. /*       r e s e t P r t y                                            */
  764. /*                                                                    */
  765. /*       No operation under Windows                                   */
  766. /*--------------------------------------------------------------------*/
  767.  
  768. void resetPrty( void )
  769. {
  770. } /* resetPrty */
  771.